/*
 * Copyright 2013 The Scripps Research Institute
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package edu.scripps.fl.entrez.internal;

import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.message.BasicNameValuePair;
import org.dom4j.Document;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class WebSessionBase implements HttpClientBase {

	private static final Logger log = LoggerFactory.getLogger(WebSessionBase.class);
	public boolean DEBUGGING = false;

	public void debugDocumentToTempFile(Document doc, boolean displayFile) throws IOException {
		File file = File.createTempFile(getClass().getName(), ".html");
		XMLWriter writer = new XMLWriter(new FileOutputStream(file));
		writer.write(doc);
		writer.close();
		if (displayFile)
			Desktop.getDesktop().open(file);
	}

	public List<NameValuePair> addParameters(List<NameValuePair> params, Object... pairs) {
		for (int ii = 0; ii < pairs.length; ii += 2)
			params.add(new BasicNameValuePair(pairs[ii].toString(), pairs[ii + 1].toString()));
		return params;
	}

	public MultipartEntity addParts(MultipartEntity entity, Collection<Object> pairs) throws UnsupportedEncodingException {
		Iterator<Object> iter = pairs.iterator();
		while (iter.hasNext()) {
			String name = iter.next().toString();
			String key = iter.hasNext() ? iter.next().toString() : "";
			entity.addPart(name, new StringBody(key.toString()));
		}
		return entity;
	}

	public MultipartEntity addParts(MultipartEntity entity, Object... pairs) throws UnsupportedEncodingException {
		for (int ii = 0; ii < pairs.length; ii += 2) {
			entity.addPart(pairs[ii].toString(), new StringBody(pairs[ii + 1].toString()));
		}
		return entity;
	}

	public List<NameValuePair> getNameValuePairs(List<Object> params) {
		List<NameValuePair> data = new ArrayList();
		for (int ii = 0; ii < params.size(); ii += 2) {
			String name = params.get(ii).toString();
			String value = "";
			if ((ii + 1) < params.size())
				value = params.get(ii + 1).toString();
			data.add(new BasicNameValuePair(name, value));
		}
		return data;
	}

	public String getPage(HttpRequestBase method) throws IOException {
		HttpResponse response = getHttpClient().execute(method);
		String page = IOUtils.toString(response.getEntity().getContent());
		if (DEBUGGING)
			debugPageToTempFile(page, DEBUGGING);
		return page;
	}

	public void debugPageToTempFile(String page, boolean displayFile) throws IOException {
		File file = File.createTempFile(getClass().getName(), ".html");
		IOUtils.write(page, new FileOutputStream(file));
		if (displayFile)
			Desktop.getDesktop().open(file);
	}

	public String getPage(String uri) throws IOException {
		log.info("Getting uri: " + uri);
		return getPage(new HttpGet(uri));
	}

	public String getPage(URI uri) throws IOException {
		log.info("Getting uri: " + uri);
		return getPage(new HttpGet(uri));
	}

	public InputStream postDocument(String uri, HttpEntity entity) throws IOException, ParserConfigurationException {
		log.info("Posting form: " + uri);
		HttpEntityEnclosingRequestBase method = new HttpPost(uri);
		method.setEntity(entity);
		HttpResponse response = getHttpClient().execute(method);
		return response.getEntity().getContent();
	}

	public String postPage(String uri, HttpEntity entity) throws IOException {
		log.info("Posting form: " + uri);
		HttpPost method = new HttpPost(uri);
		method.setEntity(entity);
		return getPage(method);
	}
}